# coding:utf-8

"""
    1: 确定用户表中每个用户的信息字段
    2：读取user.json文件
    3：写入user.json文件（检测用户使用存在），存在则不可写入
"""
import json
import os.path
import time
from common import consts
from common import error

from common import utils


class Base(object):
    def __init__(self, user_json: str, gift_json: str):
        self.user_json = user_json
        self.gift_json = gift_json

        self.__check_user_json()
        self.__check_gift_json()

        self.__init_gifts()

    def __check_user_json(self):
        utils.check_file(self.user_json)

    def __check_gift_json(self):
        utils.check_file(self.gift_json)

    def __read_users(self, time_to_str=False):
        with open(self.user_json, 'r') as f:
            rawdata = f.read()
            if rawdata != '':
                data = json.loads(rawdata)
                if time_to_str:
                    for username, v in data.items():
                        v['create_time'] = utils.timestamp_to_string(v['create_time'])
                        v['update_time'] = utils.timestamp_to_string(v['update_time'])
                        data['username'] = v
            else:
                data = {}
        return data

    def __write_user(self, **user):
        if 'username' not in user:
            raise ValueError('missing username')
        if 'role' not in user:
            raise ValueError('missing role')

        user['active'] = True
        user['create_time'] = time.time()
        user['update_time'] = time.time()
        user['gifts'] = []

        users = self.__read_users()

        if user['username'] in users:
            raise error.UserExistError('username %s had exists' % user['username'])

        users.update(
            {user['username']: user}
        )

        self.__save(users, self.user_json)

    def __change_role(self, username, role):
        users = self.__read_users()
        user = users.get(username)
        if not user:
            return False
        if role not in consts.ROLES:
            raise error.RoleError('not use role %s' % role)

        user['role'] = role
        user['update_time'] = time.time()

        users['username'] = user

        self.__save(users, self.user_json)

        return True

    def __change_active(self, username):
        users = self.__read_users()
        user = users.get(username)
        if not user:
            return False
        user['active'] = not user['active']
        user['update_time'] = time.time()
        users[username] = user

        self.__save(users, self.user_json)
        return True

    def __delete_user(self, username):
        users = self.__read_users()
        user = users.get(username)
        if not user:
            return False
        deleted_user = users.pop(username)
        self.__save(users, self.user_json)
        return deleted_user

    def __read_gifts(self):
        with open(self.gift_json) as f:
            data = json.loads(f.read())
        return data

    def __init_gifts(self):
        data = {
            'level1': {
                'level1': {},
                'level2': {},
                'level3': {},
            },
            'level2': {
                'level1': {},
                'level2': {},
                'level3': {},
            },
            'level3': {
                'level1': {},
                'level2': {},
                'level3': {},
            },
            'level4': {
                'level1': {},
                'level2': {},
                'level3': {},
            },
        }
        gifts = self.__read_gifts()
        if len(gifts) != 0:
            return

        self.__save(data, self.gift_json)

    def __write_gifts(self, first_level, second_level, gift_name, gift_count):
        if first_level not in consts.FIRSTLEVELS:
            raise error.LevelError('first level not exists')
        if second_level not in consts.SECONDLEVELS:
            raise error.LevelError('second level not exists')
        if gift_count <= 0:
            gift_count = 1
        gifts = self.__read_gifts()
        current_gift_pool = gifts[first_level]
        current_second_gift_pool = current_gift_pool[second_level]
        if gift_name in current_second_gift_pool:
            current_second_gift_pool[gift_name]['count'] += gift_count
        else:
            current_second_gift_pool[gift_name] = {
                'name': gift_name,
                'count': gift_count
            }
        gifts[first_level][second_level] = current_second_gift_pool
        self.__save(gifts, self.gift_json)

    def __gift_update(self, first_level, second_level, gift_name, gift_count=1, is_admin=False):
        assert isinstance(gift_count, int), 'gift count is a int'
        data = self.__check_and_get_gift(first_level, second_level, gift_name)
        if not data:
            return data
        gifts = data.get('gifts')
        current_gift = gifts[first_level][second_level][gift_name]
        if is_admin:
            if gift_count <= 0:
                raise error.CountError('gift count not 0')
            current_gift['count'] = gift_count
        else:
            if current_gift['count'] - gift_count < 0:
                raise error.NegativeNumberError('gift count can not negative')
            current_gift['count'] -= gift_count
        current_gift['update_time'] = time.time()
        gifts[first_level][second_level][gift_name] = current_gift
        self.__save(gifts, self.gift_json)

    def __delete_gift(self, first_level, second_level, gift_name):
        data = self.__check_and_get_gift(first_level, second_level, gift_name)
        if data == False:
            return data
        gifts = data.get('gifts')
        delete_gift_data = gifts[first_level][second_level].pop(gift_name)
        self.__save(gifts, self.gift_json)
        return delete_gift_data

    def __check_and_get_gift(self, first_level, second_level, gift_name):
        if first_level not in consts.FIRSTLEVELS:
            raise error.LevelError('first level not exists')
        if second_level not in consts.SECONDLEVELS:
            raise error.LevelError('second level not exists')
        gifts = self.__read_gifts()
        level_one = gifts[first_level]
        level_two = level_one[second_level]

        if gift_name not in level_two:
            return False

        return {
            'level1': first_level,
            'level2': second_level,
            'gifts': gifts
        }

    def __save(self, data, path):
        json_data = json.dumps(data)
        with open(path, 'w') as f:
            f.write(json_data)


if __name__ == '__main__':
    user_json = os.path.join(os.getcwd(), 'storage', 'user.json')
    gift_json = os.path.join(os.getcwd(), 'storage', 'gift.json')

    base = Base(user_json, gift_json)
    # base.write_user(username='mary', role='user')
    # base.read_users()
    # base.__delete_user('mary')

    # base.__init_gifts()

    # base.write_gifts(first_level='level1', second_level='level2', gift_name='kindle', gift_count=10)
    # base.gift_update(first_level='level1', second_level='level2', gift_name='kindle',gift_count=15)
    # result = base.delete_gift(first_level='level4', second_level='level2', gift_name='house')
    # print(result)
